package cn.max.git;

import cn.max.SystemProperties;
import cn.max.plat.db.DBUtils;
import com.gitblit.models.PathModel;
import com.gitblit.utils.JGitUtils;
import com.mongodb.DBObject;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.IndexDiff;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.treewalk.FileTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;

import java.io.File;
import java.util.List;

/**
 * Created by Max-Goday on 15/7/22.
 */
public class GitUtils {

//	public static final String LOCAL_REPOSITORY = "/Users/Max-Goday/IdeaProjects/Max/repository";

	public static final String LOCAL_REPOSITORY = SystemProperties.get("repository.dir");

	static {

		File repository = new File(LOCAL_REPOSITORY);

		if (!repository.exists()) {

			repository.mkdir();

		}

	}

	public static File getAntBuildConfigFile(String repo_name) {

		String config_file = String.valueOf(DBUtils.getRepo(repo_name).get("builder_config_dir"));

		if (config_file == null) {
			config_file = "build.xml";
		}

		return new File(LOCAL_REPOSITORY + File.separator + repo_name + File.separator + config_file);

	}

	public static Git getLocalGitRepo(String RepoName) {

		try {

			Git git = Git.open(new File(LOCAL_REPOSITORY + File.separator + RepoName));

			return git;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;

	}

	public static Git getLocalUpdatedGitRepo(String RepoName) {

		try {

			Git git = Git.open(new File(LOCAL_REPOSITORY + File.separator + RepoName));

			pull(RepoName);

			return git;

		} catch (Exception e) {
//			e.printStackTrace();
		}

		return null;

	}

	public static void pull(String RepoName) {

		DBObject repo = DBUtils.getRepo(RepoName);

		Git git = getLocalGitRepo(RepoName);

		try {

			git.checkout().setName("master").call();

			if (repo.get("username") != null) {

				git.pull().setCredentialsProvider(_getGitCredits(repo.get("username"), repo.get("password"))).call();

			} else {

				git.pull().call();

			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public static Git clone(String URL, String ProjName, String User, String password) {

		File _local_proj_repo = null;

		try {

			_local_proj_repo = new File(LOCAL_REPOSITORY + File.separator + ProjName);

			if (_local_proj_repo.exists()) {

				return getLocalGitRepo(ProjName);

			}

			_local_proj_repo.mkdir();

			if (User != null) {

				return _git_clone_with_credit(URL, _local_proj_repo, _getGitCredits(User, password));

			}

			return _git_clone(URL, _local_proj_repo);


		} catch(Exception e) {
			_local_proj_repo.deleteOnExit();
			e.printStackTrace();
		}

		return null;

	}

	public static boolean checkout(String ProjName, String commit) {

		Git git = getLocalUpdatedGitRepo(ProjName);

		try {

			git.checkout().setName(commit).call();

		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

		return true;

	}

	private static Git _git_clone_with_credit(String URL, File repo_dir, CredentialsProvider cp) throws Exception{

		return Git.cloneRepository()
				.setURI(URL)
				.setCredentialsProvider(cp)
				.setDirectory(repo_dir)
				.call();
	}

	private static Git _git_clone(String URL, File repo_dir) throws Exception{

		return Git.cloneRepository()
				.setURI(URL)
				.setDirectory(repo_dir)
				.call();
	}

	private static CredentialsProvider _getGitCredits(Object user, Object password) {
		return new UsernamePasswordCredentialsProvider(String.valueOf(user), String.valueOf(password));
	}

	public static void main(String[] args) {

		Git g = getLocalGitRepo("cecep-ecm");

		try {

			RevWalk walk = new RevWalk(g.getRepository());

			RevCommit commit = walk.parseCommit(ObjectId.fromString("bfa8b061259e57236a603cc3a35d75c5eaa761b2"));

			System.out.println(commit);
			System.out.println(commit.getName());
			System.out.println(commit.getFullMessage());
			System.out.println(commit.getCommitterIdent().getEmailAddress());


			RevTree tree = commit.getTree();

			TreeWalk tw = TreeWalk.forPath(g.getRepository(), "src.config/system.properties", tree);


			FileTreeIterator fileTreeItr = new FileTreeIterator(g.getRepository());


			IndexDiff indexDiff = new IndexDiff(g.getRepository(), commit.getId(), fileTreeItr);

			System.out.println(indexDiff.getChanged());
			System.out.println(indexDiff.getAdded());


			List<PathModel.PathChangeModel> s = JGitUtils.getFilesInCommit(g.getRepository(), commit);

			for (int i = 0; i < s.size(); i ++) {

				PathModel.PathChangeModel blob = s.get(i);

				System.out.println(">>>>>>>>>>>>>>");
				System.out.println(blob.path);
				System.out.println(blob.changeType);
				System.out.println(blob.mode);
				System.out.println(blob.size);
				System.out.println(blob.objectId);
				System.out.println(blob.commitId);

			}

		} catch (Exception e) {
			e.printStackTrace();

		}

	}


}
